#pragma once

#include "vehicle_operation_dispatcher.h"
#include "kernel/agv/agv_entity.h"
#include "kernel/agv/i_agv_status_provider.h"
#include "kernel/interfaces/ILogger.h"
#include "kernel/interfaces/Result.h"
#include "kernel/dtos/agv_dto.h"
#include "infrastructure/services/common_service.h"
#include <QObject>
#include <QTimer>
#include <QHash>
#include <QSet>
#include <QString>
#include <memory>
#include <unordered_map>
#include <vector>
#include <string>
#include <map>
#include <optional>
#include <chrono>

namespace application {
class MapApplicationService;
namespace vehicle {

/**
 * @brief 车辆导航请求信息
 */
struct VehicleNavRequest {
    std::string startStation;
    std::string goalStation;
    int agvNumber;
};

/**
 * @brief 车辆服务 - 应用层车辆管理用例
 * @details 负责车辆的宏观流程控制，包括：
 *          - 车辆生命周期管理
 *          - 车辆任务调度
 *          - 车辆状态查询
 *          - 通过 VehicleOperationDispatcher 分派具体命令
 */
class VehicleService : public QObject {
    Q_OBJECT

public:
    enum class AutoChargeReason {
        IdleCharge,
        LowBattery
    };
    Q_ENUM(AutoChargeReason)

    explicit VehicleService(
        std::shared_ptr<infrastructure::services::CommonService> commonService,
        std::shared_ptr<VehicleOperationDispatcher> dispatcher,
        std::shared_ptr<MapApplicationService> mapService = std::shared_ptr<MapApplicationService>(),
        QObject* parent = nullptr
    );
    ~VehicleService() = default;

    // ==================== 车辆管理 ====================

    /**
     * @brief 注册新车辆
     * @param agvNumber 车辆编号
     * @param commandImpl 车辆命令实现
     */
    kernel::Result<void> registerVehicle(
        int agvNumber,
        std::shared_ptr<kernel::agv::IAgvCommand> commandImpl,
        kernel::agv::AgvType type = kernel::agv::AgvType::MKLM
    );

    /**
     * @brief 注册车辆状态提供者
     * @param agvNumber 车辆编号
     * @param statusProvider 状态提供者实现
     */
    kernel::Result<void> registerVehicleStatusProvider(
        int agvNumber,
        std::shared_ptr<kernel::agv::IAgvStatusProvider> statusProvider
    );

    /**
     * @brief 注销车辆
     */
    void unregisterVehicle(int agvNumber);

    /**
     * @brief 获取车辆实体
     */
    kernel::agv::AgvEntity* getVehicle(int agvNumber);
    const kernel::agv::AgvEntity* getVehicle(int agvNumber) const;

    /**
     * @brief 获取所有车辆
     */
    std::vector<kernel::agv::AgvEntity*> getAllVehicles();

    /**
     * @brief 获取车辆数量
     */
    size_t getVehicleCount() const;

    // ==================== 车辆导航操作 ====================

    /**
     * @brief 车辆导航到站点列表
     */
    kernel::Result<void> moveVehicleToStations(
        int agvNumber,
        const std::vector<std::string>& stations,
        const std::string& operation = ""
    );

    /**
     * @brief 车辆导航到单个站点
     */
    kernel::Result<void> moveVehicleToStation(
        int agvNumber,
        const std::string& sourceId,
        const std::string& targetId
    );

    /**
     * @brief 清除车辆任务
     */
    kernel::Result<void> clearVehicleTask(int agvNumber);

    /**
     * @brief 暂停车辆任务
     */
    kernel::Result<void> pauseVehicleTask(int agvNumber);

    /**
     * @brief 恢复车辆任务
     */
    kernel::Result<void> resumeVehicleTask(int agvNumber);

    // ==================== 车辆硬件控制 ====================

    /**
     * @brief 控制车辆顶升
     */
    kernel::Result<void> controlVehicleJack(int agvNumber, bool raise);

    /**
     * @brief 车辆前往充电
     */
    kernel::Result<void> sendVehicleToCharge(int agvNumber, const std::string& chargePoint);

    /**
     * @brief 车辆退出充电
     */
    kernel::Result<void> stopVehicleCharging(int agvNumber);

    /**
     * @brief 控制门
     */
    kernel::Result<void> controlDoor(int agvNumber, int doorId, bool open);
    kernel::Result<void> switchMap(int agvNumber, const std::string& mapName, const std::string& switchPoint);

    // ==================== DTO 查询方法（用于 Presentation 层）====================

    /**
     * @brief 获取所有车辆的展示信息（DTO）
     * @return AgvInfoDTO 列表
     */
    std::vector<kernel::dtos::AgvInfoDTO> getAllAgvs();

    /**
     * @brief 获取单个车辆的展示信息（DTO）
     * @param agvNumber 车辆编号
     * @return AgvInfoDTO
     */
    kernel::dtos::AgvInfoDTO getAgv(int agvNumber);

    /**
     * @brief 开始充电
     * @param agvNumber 车辆编号
     * @param chargePoint 充电点
     * @return 操作结果
     */
    bool startCharging(int agvNumber, const std::string& chargePoint);

    /**
     * @brief 停止充电
     * @param agvNumber 车辆编号
     * @return 操作结果
     */
    bool stopCharging(int agvNumber);

    /**
     * @brief 取消车辆任务
     * @param agvNumber 车辆编号
     * @return 操作结果
     */
    bool cancelAgvTask(int agvNumber);

    /**
     * @brief 控制顶升
     * @param agvNumber 车辆编号
     * @param raise 是否顶升
     * @return 操作结果
     */
    bool controlJack(int agvNumber, bool raise);

    /**
     * @brief 暂停任务
     * @param agvNumber 车辆编号
     * @return 操作结果
     */
    bool pauseAgvTask(int agvNumber);

    /**
     * @brief 重置自动充电定时器
     * @param agvNumber 车辆编号
     * @details 重置空闲充电和低电量充电的触发状态,将空闲计数从零开始
     */
    void resetAutoChargeTimer(int agvNumber);

    /**
     * @brief 恢复任务
     * @param agvNumber 车辆编号
     * @return 操作结果
     */
    bool resumeAgvTask(int agvNumber);

    // ==================== 车辆查询 ====================

    /**
     * @brief 获取空闲车辆列表
     */
    std::vector<kernel::agv::AgvEntity*> getIdleVehicles();

    /**
     * @brief 获取指定地图上的车辆
     */
    std::vector<kernel::agv::AgvEntity*> getVehiclesOnMap(const std::string& mapName);

    /**
     * @brief 获取所有导航任务请求
     * @param mapName 地图名称
     * @param enforce 是否强制包含所有车辆（即使没有新任务）
     */
    std::vector<VehicleNavRequest> getAllNavRequests(
        const std::string& mapName,
        bool enforce = false
    );

    /**
     * @brief 获取车辆当前站点
     */
    std::string getVehicleCurrentStation(int agvNumber) const;

    /**
     * @brief 获取车辆目标站点
     */
    std::string getVehicleTargetStation(int agvNumber) const;

    /**
     * @brief 检查车辆是否在导航中
     */
    bool isVehicleNavigating(int agvNumber) const;

    /**
     * @brief 设置车辆导航任务（目标点）
     */
    void setVehicleNavTask(int agvNumber, const std::string& goal);

    /**
     * @brief 获取车辆导航任务（起点和终点）
     */
    void getVehicleNavTask(
        int agvNumber,
        std::string& startStation,
        std::string& goalStation
    ) const;

    /**
     * @brief 请求获取车辆当前地图
     */
    kernel::Result<void> requestVehicleMap(int agvNumber);

    /**
     * @brief 重发上次命令
     */
    kernel::Result<void> resendLastCommand(int agvNumber);

    // ==================== 车辆状态管理 ====================

    /**
     * @brief 检查车辆是否在线（基于上传时间）
     */
    void updateVehicleOnlineStatus();

    /**
     * @brief 自动充电管理（空闲车辆、低电量车辆）
     */
    void manageAutoCharging();

signals:
    void vehicleRegistered(int agvNumber);
    void vehicleUnregistered(int agvNumber);
    void vehicleStatusChanged(int agvNumber);
    void vehicleIdle();  // 所有车辆空闲
    void autoChargeRequested(int agvNumber, AutoChargeReason reason, int batteryLevel);

public slots:
    /**
     * @brief 处理检测到的未知MKLM AGV（动态注册）
     * @param agvNumber AGV编号
     * @param status 初始状态数据
     */
    void onUnknownMklmAgvDetected(int agvNumber, kernel::dtos::MklmAgvStatusDTO status);

private:
    std::shared_ptr<kernel::ILogger> m_logger;
    std::shared_ptr<VehicleOperationDispatcher> m_dispatcher;
    std::weak_ptr<MapApplicationService> m_mapService;
    QTimer* m_healthCheckTimer{nullptr};

    // 车辆实体映射 (agvNumber -> AgvEntity)
    std::unordered_map<int, std::unique_ptr<kernel::agv::AgvEntity>> m_vehicles;

    // 状态提供者映射 (agvNumber -> StatusProvider)
    std::unordered_map<int, std::shared_ptr<kernel::agv::IAgvStatusProvider>> m_statusProviders;
    struct AutoChargeState {
        bool idleChargeTriggered{false};
        bool lowBatteryTriggered{false};
        std::optional<std::chrono::system_clock::time_point> idleResetTime;
    };
    std::unordered_map<int, AutoChargeState> m_autoChargeStates;
    struct AgvAreaSnapshot {
        int floor{-1};
        QSet<QString> areaIds;
    };
    QHash<int, AgvAreaSnapshot> m_agvAreaSnapshots;

    // 辅助方法：检查车辆是否存在
    bool vehicleExists(int agvNumber) const;

    /**
     * @brief 处理 AGV 状态更新
     * @param agvNumber AGV 编号
     * @param status 状态 DTO
     */
    void handleStatusUpdate(int agvNumber, const kernel::dtos::AgvStatusDTO& status);
    void openDoorsForUpcomingSegments(kernel::agv::AgvEntity* agv,
                                      const kernel::dtos::AgvStatusDTO& status);
    void closeDoorsForFinishedSegments(
        kernel::agv::AgvEntity* agv,
        const std::vector<std::string>& previousFinished,
        const std::vector<std::string>& currentFinished);

    /**
     * @brief 路径比对（从后往前比对unfinished_path和新路径）
     * @param unfinishedPath AGV当前未完成路径
     * @param newStations 新的目标站点列表
     * @return true表示路径相同，不需要下发
     */
    bool isSameRoute(
        const std::vector<std::string>& unfinishedPath,
        const std::vector<std::string>& newStations
    ) const;

    /**
     * @brief 计算路径起始索引（处理finished_path）
     * @param finishedPath AGV当前已完成路径
     * @param newStations 新的目标站点列表
     * @return 起始索引（0表示从第一个站点开始）
     */
    int calculateRouteStartIndex(
        const std::vector<std::string>& finishedPath,
        const std::vector<std::string>& newStations
    ) const;

    /**
     * @brief 将 AgvEntity 转换为 AgvInfoDTO（用于 Presentation 层）
     * @param entity AGV 实体
     * @return AgvInfoDTO
     */
    kernel::dtos::AgvInfoDTO entityToInfoDTO(const kernel::agv::AgvEntity* entity) const;

    void updateAgvAreaOccupancy(kernel::agv::AgvEntity* agv,
                                const std::vector<std::string>& previousAreas,
                                const std::vector<std::string>& currentAreas,
                                const QString& currentMapName);
    void clearAgvAreaOccupancy(int agvNumber);

private slots:
    void onHealthCheckTimeout();
};

} // namespace vehicle
} // namespace application
